<?php
/***
 * Candy框架 队列类
 * 
 * $Author: 刘森 (fingerboy@qq.com) $
 * $Date: 2019-08-03 08:31:01 $   
 */

declare (strict_types = 1);
namespace Candy\Core;

defined('CANDY') OR die('You Are A Bad Guy. o_O???');

final Class Queue {
	
	private static $_handler=null;
	private static $tabprefix=null;
	
	/**
     * 初始化
	 */
	public static function init(): object
	{
		//表前缀
		$this->tabprefix = G('TABPREFIX');
		
		//启用cache
		if(defined('USEMEM')){
			$memCache = memCache();
			self::$_handler = $memCache;
		}else{
			//写入到文件  不推荐  有IO
			self::$_handler = N('FileCache');
		}
        return self::$_handler;
    }
    
    /**
     * 删除 key 集合中的子集
	 *
     * @param unknown $key
     * @param unknown $son_key
     * @return boolean
     */
    public static function srem(string $key,string $son_key): bool
	{
		$key = $this->tabprefix . $key;
        $data= (array) self::$_handler->get($key);
        if(!count($data)){
            return false;
        }
        foreach ($data as $k=>$v){
            if($v==$son_key){
                unset($data[$k]);
            }
        }
        unset($data[$son_key]);
        return self::$_handler->set($key, $data);
    }
    
    
    /**
     * 加入
	 *
     * @param string $key 表头
     * @param string $value 值
     */
    public static function push(string $key,string $value): bool
	{
        self::init();
		$key = $this->tabprefix . $key;
		$data= (array) self::$_handler->get($key);
        array_push($data,$value);
        return self::$_handler->set($key, $data);
    }
	
    /**
     * 出列 堵塞 当没有数据的时候，会一直等待下去
	 *
     * @param string $key 表头
     * @param number $timeout 延时   0无限等待
     * @return Ambigous <NULL, mixed>
     */
    public static function pop(string $key,int $timeout=0):mixed
	{
        self::init();
		$key = $this->tabprefix . $key;
		$res=null;
        $wh=true;
		$second=0;
        while ($wh){
            $data= (array) self::$_handler->get($key);
            if(count($data)!=0){
                $res=array_shift($data);
                self::$_handler->set($key, $data);
                $wh=false;
                break;
            }

            if($timeout==0){
                sleep(1);
            }elseif($timeout>0 && $second<$timeout){
                sleep(1);
                $second++;
            }else{
                break;
            }
        }
        return $res;
    }
	
    /**
     * 关闭
	 */
    public function close(): bool
	{
        self::$_handler=null;
        return true;
    }
}
